package com.anjingsi.tools.queue;


import com.anjingsi.tools.dto.HeroNode;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;

import java.util.List;


/**
 * @program: 环形单向链表
 * @description
 * @author: 安静思
 * @create: 2019-12-06 09:27
 **/
@Slf4j
public class CircleSingleLinked {

    /**
     * 记录头节点
     */
    private HeroNode head ;

    /**
     * 添加节点到链表
     */
    public void add(HeroNode heroNode) {
        /**
         * 节点没有任何的元素的时候
         */
        if(head == null){
            head = heroNode;
            if(heroNode.getNext() == null){
                heroNode.setNext(heroNode);
            }else {

            }
            return;
        }
        //查找最后的元素
        HeroNode temp = head;
        while (true){
            if(temp.getNext().getNo() == head.getNo()){
                break;
            }
            temp = temp.getNext();
        }
        //当退出 while 循环时，temp 就指向了链表的最后 //将最后这个节点的 next 指向 新的节点
        heroNode.setNext(head);
        temp.setNext(heroNode);
    }

    /**
     * 指定位置插入  如果有这个排名，则添加失败，并给出提示
     * @param heroNode
     */
    public void addByOrder(HeroNode heroNode) {
        HeroNode temp = head;

        /**
         * 标志添加的编号是否存在，默认为 false
         */
        boolean flag = false;
        while(true) {
            //说明 temp 已经在链表的最后
            if(temp.getNext().getNo() == head.getNo()) {
                break;
            }
            //位置找到，就在 temp 的后面插入
            if(temp.getNext().getNo() > heroNode.getNo()) {
                break;
            } else if (temp.getNext().getNo() == heroNode.getNo()) {
                //说明希望添加的 heroNode 的编号已然存在
                flag = true;
                break;
            }
            temp = temp.getNext();
        }
        //判断 flag 的值  true不能添加，说明编号存在
        if(flag) {
            log.info("准备插入的英雄的编号 {} 已经存在了, 不能加入", heroNode.getNo());
        } else {
            //插入到链表中, temp 的后面
            heroNode.setNext(temp.getNext());
            temp.setNext(heroNode);
        }
    }


    /**
     * 根据标号来修改节点
     */
    public void update(HeroNode newHeroNode) {
        if(head == null){
            log.info("修改的节点不存在！");
            return;
        }
        HeroNode temp = head;
        boolean flag = false;
        while (true){
            if(temp.getNo() == newHeroNode.getNo()){
                flag = true;
                break;
            }
            if(temp.getNext().getNo() == head.getNo()){
                break;
            }
            temp = temp.getNext();
        }
        if(flag){
            temp.setName(newHeroNode.getName());
        }else {
            log.info("修改的节点不存在，节点的no为：{}",newHeroNode.getNo());
        }
    }


    /**
     * 删除节点
     * @param heroNode
     */
    public void delete(HeroNode heroNode) {
        HeroNode temp = head;

        /**
         * 标志是否找到待删除节点的
         */
        boolean flag = false;
        while (true) {
            if (temp.getNext().getNo() == head.getNo() || temp.getNext().getNo() == heroNode.getNo()) {
                //找到的待删除节点的前一个节点temp
                flag = true;
                break;
            }
            //temp 后移，遍历
            temp = temp.getNext();
        }
        if (flag) {
            //可以删除
            temp.setNext(temp.getNext().getNext());
        } else {
            log.info("要删除的 {} 节点不存在", heroNode.getNo());
        }
    }

    /**
     * 查找节点
     * @param no
     */
    public HeroNode findByNo(int no) {
        HeroNode temp = head;

        /**
         * 标志是否找到
         */
        boolean flag = false;
        while (true) {
            if(temp.getNext().getNo() == head.getNo()){
                break;
            }
            if (temp.getNo() == no) {
                flag = true;
                break;
            }
            //temp 后移，遍历
            temp = temp.getNext();
        }
        if (flag) {
            return head;
        } else {
            log.info("要查找的 {} 节点不存在", no);
        }
        return null;
    }

    /**
     * 显示链表
     */
    public List<HeroNode> list() {
        if(head == null){
            log.info("链表为空");
            return null;
        }
        List<HeroNode> result = Lists.newArrayList();
        HeroNode temp = head.getNext();
        //判断是否添加了头节点
        boolean flag = false;
        while(true) {
            //判断是否到链表最后
            if(temp.getNo() == head.getNo()) {
                if(!flag){
                    addHeroNodeToList(temp,result,0);
                    flag = true;
                }
                break;
            }
            addHeroNodeToList(temp,result,null);
            temp = temp.getNext();
        }
        return result;
    }

    private void addHeroNodeToList(HeroNode temp, List<HeroNode> result, Integer index){
        HeroNode heroNode = new HeroNode(temp.getNo(),temp.getName(),temp.getNickName());
        heroNode.setNext(new HeroNode(temp.getNext().getNo(),temp.getNext().getName(),temp.getNext().getNickName()));
        if(index == null){
            result.add(heroNode);
        }else {
            result.add(index,heroNode);
        }

    }

    /**
     * 删除当前序号的  并返回下一节点返回
     */
    public DeleteHeroNodeDto deleteByIndex(int index) {
        HeroNode temp = head;
        DeleteHeroNodeDto deleteHeroNodeDto = new DeleteHeroNodeDto();
        for (int i = 0; i <= index; i++) {
            if(i == index){
                delete(temp);
                deleteHeroNodeDto.setIndex(temp.getNo());
            }
            temp = temp.getNext();
        }
        deleteHeroNodeDto.setHeroNode(temp);
        return deleteHeroNodeDto;
    }

    public void init(HeroNode heroNode) {
        head = null;
        add(heroNode);
    }
}




